#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <error.h>
#include <vector>
#include <sys/wait.h>
#include <sys/types.h>

using namespace std;

// int main()
// {
//     //执行什么操作
//     char* const argv[] = {"ps","-ef",NULL};
//     //环境变量
//     char *const envp[] = {"PATH=/home/zjiu/zjiu/250731","TERM=xterm",NULL};

//     //执行哪个可执行程序（程序路径），对该可执行程序进行那些操作，最后以NULL结尾
//     execl("/bin/ps","ps","-ef",NULL);

//     //带p的，可以使用环境变量，无需写全路径（PATH路径重复时，先运行第一个，从左到右依次匹配执行）
//     execlp("ps","ps","-ef",NULL);//前两个参数重复，但是语义不同，第一个表示你想执行谁，由于带了p可以自动搜索路径，所以没有全路径
//     //第二个参数表示你想对这个可执行程序执行什么操作，怎么执行

//     //带e的需要自己组装环境变量
//     execle("/bin/ps","ps","-ef",NULL,envp);

//     //带v的使用数组
//     execv("/bin/ps",argv);

//     execvp("ps",argv);

//     execve("/bin/ps",argv,envp);

//     return 0;
// }

// typedef void (*handler_t )();//函数指针
// vector<handler_t> handlers;//函数指针数组

// void func_one()
// {
//     printf("这是临时任务1\n");
// }

// void func_two()
// {
//     printf("这是临时任务2\n");
// }

// void Load()
// {
//     handlers.push_back(func_one);
//     handlers.push_back(func_two);
// }

// void handler()
// {
//     if(handlers.empty())
//         Load();
//     for(auto func : handlers)
//     {
//         func();
//     }
// }

// // 非阻塞式等待
// int main()
// {
//     int id = fork();
//     if (id < 0)
//     {
//         printf("%s fork error\n", __FUNCTION__);
//         return 1;
//     }
//     else if (id == 0)
//     {
//         printf("child is running,pid : %d\n", getpid());
//         sleep(2);
//         exit(456);
//     }
//     else
//     {
//         int status = 0;
//         pid_t ret = 0;

//         do
//         {
//             // 我们只能通过系统调用获得进程退出信息
//             ret = waitpid(-1, &status, WNOHANG); // 非阻塞式等待
//             if(ret == 0)
//                 printf("this is test for wait\n");

//             handler();
//         } while (ret == 0);

//         if (WIFEXITED(status) && ret == id)
//         {
//             printf("wait child 5s success,child return code is: %d\n", WEXITSTATUS(status));
//         }
//         else
//         {
//             printf("wait child fail,return.\n");
//             return 1;
//         }
//     }

//     return 0;
// }

// 阻塞式等待
// int main()
// {
//     int id = fork();
//     if (id < 0)
//     {
//         printf("%s fork error\n", __FUNCTION__);
//         return 1;
//     }
//     else if (id == 0)
//     {
//         printf("child is running,pid : %d\n", getpid());
//         sleep(2);
//         exit(456);
//     }
//     else
//     {
//         int status = 0;
//         //我们只能通过系统调用获得进程退出信息
//         pid_t ret = waitpid(-1, &status, 0); // 阻塞式等待，相当于wait(nulllptr)
//         printf("this is test for wait\n");

//         if (WIFEXITED(status) && ret == id)
//         {
//             printf("wait child 5s success,child return code is: %d\n", WEXITSTATUS(status));
//         }
//         else
//         {
//             printf("wait child fail,return.\n");
//             return 1;
//         }
//     }

//     return 0;
// }

// int main()
// {
//     int id = fork();

//     if(id < 0)
//     {
//         perror("fork");
//         return 1;
//     }
//     else if(id == 0)
//     {
//         sleep(20);
//         exit(123);
//     }
//     else
//     {
//         int st;
//         int ret = wait(&st);

//         if(ret > 0 && (st & 0x7f) == 0)//正常退出
//             printf("child exit code : %d\n",(st>>8)&0xFF);
//         else
//             printf("sig code : %d\n",st&0x7F);//异常退出，打印终止信号
//     }

//     return 0;
// }